x86: tolerate running on EFI runtime services page tables in map_domain_page()
authorJan Beulich <jbeulich@suse.com>
Mon, 27 Oct 2014 15:43:12 +0000 (16:43 +0100)
committerJan Beulich <jbeulich@suse.com>
Mon, 27 Oct 2014 15:43:12 +0000 (16:43 +0100)
In the event of a #PF while in an EFI runtime service function we
otherwise can't dump the page tables, making the analysis of the
problem more cumbersome.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/domain_page.c
xen/arch/x86/efi/stub.c
xen/common/efi/runtime.c
xen/include/xen/efi.h

index 3903952d2d47fc781562acb52a7096c3a23a7cea..158a1645d74fa9c38e6417b2c40f616db4d4017f 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <xen/domain_page.h>
+#include <xen/efi.h>
 #include <xen/mm.h>
 #include <xen/perfc.h>
 #include <xen/pfn.h>
@@ -37,11 +38,14 @@ static inline struct vcpu *mapcache_current_vcpu(void)
      */
     if ( unlikely(pagetable_is_null(v->arch.guest_table)) && is_pv_vcpu(v) )
     {
+        unsigned long cr3;
+
         /* If we really are idling, perform lazy context switch now. */
         if ( (v = idle_vcpu[smp_processor_id()]) == current )
             sync_local_execstate();
         /* We must now be running on the idle page table. */
-        ASSERT(read_cr3() == __pa(idle_pg_table));
+        ASSERT((cr3 = read_cr3()) == __pa(idle_pg_table) ||
+               (efi_enabled && cr3 == efi_rs_page_table()));
     }
 
     return v;
index 8916a2ec7be95fc00f363eebddc2d789bf88cbc8..b8f49f873de960010e109d863ca0b382689af2dd 100644 (file)
@@ -9,6 +9,12 @@ const bool_t efi_enabled = 0;
 
 void __init efi_init_memory(void) { }
 
+paddr_t efi_rs_page_table(void)
+{
+    BUG();
+    return 0;
+}
+
 unsigned long efi_get_time(void)
 {
     BUG();
index 1c43d109fcfbf3407bdf11252fcfd1ba0d128b72..553ff9170245ad686ccd8fdabbee4785165f1989 100644 (file)
@@ -98,6 +98,11 @@ void efi_rs_leave(unsigned long cr3)
     stts();
 }
 
+paddr_t efi_rs_page_table(void)
+{
+    return virt_to_maddr(efi_l4_pgtable);
+}
+
 unsigned long efi_get_time(void)
 {
     EFI_TIME time;
index 8a2b78892d3b69175588553fe02ac4c5fd70487c..5e02724572b798b7691ab14c6d04e4ee4faec48b 100644 (file)
@@ -28,6 +28,7 @@ struct xenpf_efi_runtime_call;
 struct compat_pf_efi_runtime_call;
 
 void efi_init_memory(void);
+paddr_t efi_rs_page_table(void);
 unsigned long efi_get_time(void);
 void efi_halt_system(void);
 void efi_reset_system(bool_t warm);